<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            display: flex;
            flex-direction: row;
            box-sizing: border-box;
        }

        .middle {
            width: 50px;
            margin: 0 2rem;
            align-self: center;
        }

        .left,
        .right {
            width: 300px;
            border: 2px solid #999;
            max-height: 300px;
            min-height: 300px;
            overflow-y: scroll;
        }

        .left {
            overflow: hidden;
        }

        .left textarea {
            border: none;
            width: 100%;
            height: 100%;
            resize: none;

        }
    </style>
</head>

<body>
    <div class="box">
        <div class="left">
            <textarea rows="10"></textarea>
        </div>
        <div class="middle">
            <button>读取</button>
        </div>
        <div class="right">
            <div class="result">

            </div>
        </div>
    </div>

    <script>
        class NormalReader {
            constructor(txt) {
                this.txt = txt;
                this.buffer = this.txt.split(/[\r\n]/g);
                this.index = 0;
            }
            readLine() {
                if (this.index > this.buffer.length - 1)
                    return;

                return this.buffer[this.index++];
            }
        }
        class Decorator{
            constructor(reader){
                this.reader = reader;
            }
            readLine(){
                return this.reader.readLine();
            }
        }
        class ColoredReader extends Decorator {
            readLine() {
                const str = super.readLine();
                if (!str) return;

                const span = document.createElement("span");
                span.style.color = "red";
                span.innerHTML = str;

                return span.outerHTML;
            }
        }
        class BoxedReader extends Decorator{
            readLine(){
                const str = super.readLine();
                if (!str) return;

                const span = document.createElement("div");
                span.style.background = "green";
                span.innerHTML = str;
                span.style.height="50px"
                span.style.border = "1px solid #999"

                return span.outerHTML;
            }
        }

        class NumberReader extends Decorator{
            constructor(txt){
                super(txt);
                this.num = 1;
            }
            readLine(){
                const str = super.readLine();
                if (!str) return;

                return `${this.num++}   -   ${str}`;
            }
        }


        const btn = document.querySelector("button");
        const result = document.querySelector(".result");

        btn.addEventListener("click", e => {
            const txt = document.querySelector("textarea").value;
            const reader = new BoxedReader(new NumberReader(new NormalReader(txt)));
            let str;
            while ((str = reader.readLine())) {
                const div = document.createElement("div");
                div.innerHTML = str;

                result.append(div);
            }
        })
    </script>
</body>

</html>